package com.oneinlet

import java.io.*
import java.net.URL
import java.nio.charset.Charset

/**
 * Created by WangZiHe on 2018/5/13
 * QQ/WeChat:648830605
 * QQ-Group:368512253
 * Blog:www.520code.net
 * Github:https://github.com/yancheng199287
 */

/**
 * io流帮手，帮助你人性化简单处理各种文件读写操作，编码转换，超简洁api
 * @author  WangZihe
 */
object YCStream {

    /**
     * 默认缓冲区大小，读取流无需指定
     * */
    private val DEFAULT_BUFFER_SIZE = 4 * 1024

    /**
     * 文件结束符标识
     * */
    private val EOF = -1

    /**
     * 默认编码 UTF-8
     * */
    private val DEFAULT_CHARSET: Charset = Charset.forName("UTF-8")

    /**
     *  读取指定的流，转化为字符串，注意该方法只适合读取字符相关的文件，如txt文档类的
     *  @param reader 字符输入流
     * */
    fun toString(reader: Reader): String {
        val buffer = CharArray(DEFAULT_BUFFER_SIZE)
        val stringBuilder = StringBuilder()
        var n: Int
        while (true) {
            n = reader.read(buffer)
            if (EOF == n) break
            stringBuilder.append(buffer, 0, n)
        }
        reader.close()
        return stringBuilder.toString()
    }

    /**
     *  读取指定的流，转化为字符串，注意该方法只适合读取字符相关的文件，如txt文档类的，已经默认指定编码UTF-8
     *  @param inputStream 字节输入流
     * */
    fun toString(inputStream: InputStream): String {
        return InputStreamReader(inputStream, DEFAULT_CHARSET).use {
            toString(it)
        }
    }

    /**
     *  读取指定Http流，转化为字符串
     *  @param url 一个网址链接，读取返回的内容
     * */
    fun toStringFromWeb(url: String): String {
        return InputStreamReader(URL(url).openStream(), DEFAULT_CHARSET).use {
            toString(it)
        }
    }

    /**
     *  读取指定Http流，转化为字符串
     *  @param filePath 一个文件路径，确保在该路径下存在
     * */
    fun toStringFromFilePath(filePath: String): String {
        return InputStreamReader(FileInputStream(File(filePath)), DEFAULT_CHARSET).use {
            toString(it)
        }
    }

    /**
     *  读取指定文件，转化为字符串
     *  @param file 一个文件对象
     * */
    fun toStringFromFile(file: File): String {
        return InputStreamReader(FileInputStream(file), DEFAULT_CHARSET).use {
            toString(it)
        }
    }


    /**
     * 从一个字节输入流写入到一个字节输出流
     * @param inputStream 字节输入流
     *  @param outputStream 字节输出流
     *  @return 返回读取的总的字节数
     * */
    fun write(inputStream: InputStream, outputStream: OutputStream): Long {
        val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
        var count: Long = 0
        var n: Int
        while (true) {
            n = inputStream.read(buffer)
            if (EOF == n) break
            outputStream.write(buffer, 0, n)
            count += n.toLong()
        }
        return count
    }


    /**
     * 从一个字符输入流写入到一个字符输出流
     * @param reader 字节输入流
     *  @param writer 字节输出流
     * */
    fun write(reader: Reader, writer: Writer): Long {
        val buffer = CharArray(DEFAULT_BUFFER_SIZE)
        var count: Long = 0
        var n: Int
        while (true) {
            n = reader.read(buffer)
            if (EOF == n) break
            writer.write(buffer, 0, n)
            count += n.toLong()
        }
        return count
    }

    /**
     * 追加内容到指定的文件
     * @param file 需要追加的文件
     *  @param content 追加的字符串内容
     *  @param newLine 追加内容的时候是否需要换行，默认换行
     * */
    fun appendContentToFile(file: File, content: String, newLine: Boolean = true) {
        val fileWriter = FileWriter(file, true)
        if (newLine) {
            fileWriter.write("\n" + content)
        } else {
            fileWriter.write(content)
        }
        fileWriter.close()
    }

}
